package com.cloudpivot.receivales.contract.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cloudpivot.receivales.contract.domain.crmcontract.CrmContract;
import com.cloudpivot.receivales.contract.domain.crmcontract.CrmContractItem;
import com.cloudpivot.receivales.contract.entity.bpmcontract.BpmContractAppendV3Entity;
import com.cloudpivot.receivales.contract.entity.bpmcontract.BpmContractReplaceV3Entity;
import com.cloudpivot.receivales.contract.entity.bpmcontract.BpmContractV3Entity;
import com.cloudpivot.receivales.contract.repository.bpm.BpmContractAppendRepository;
import com.cloudpivot.receivales.contract.repository.bpm.BpmContractReplaceRepository;
import com.cloudpivot.receivales.contract.repository.bpm.BpmContractRepository;
import com.cloudpivot.receivales.contract.service.ContractAffairsService;
import com.cloudpivot.receivales.contract.service.http.HttpAPIServiceForCrm;
import com.cloudpivot.receivales.contract.util.StrUtil;
import com.cloudpivot.receivales.ding.util.DingUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;

import static com.cloudpivot.receivales.contract.util.StrUtil.object2Double;

/**
 * 推送 合同服务 V3
 */

@Service
@Slf4j
public class ContractAffairsServiceImpl implements ContractAffairsService {

    @Autowired
    private BpmContractRepository bpmContractRepository;
    @Autowired
    private BpmContractAppendRepository bpmContractAppendRepository;

    @Autowired
    private BpmContractReplaceRepository bpmContractReplaceRepository;

    @Autowired
    private HttpAPIServiceForCrm httpAPIServiceForCrm;

    @Autowired
    private ObjectMapper objectMapper;

    @Value("${myprops.crmurl}")
    private String CRMAPI;


    /**
     * 临时处理
     * 单独更新offerJson groupJson字段
     *
     * @param id Bpm 记录Id
     * @return
     */
    @Override
    public String updateContractAppendToCrmForSingleField(String id, String contractGuid) {
        BpmContractV3Entity contractEntity = bpmContractRepository.getBpmContract(id);

        //更新主表信息
        String reqUrlMain = String.format("%s%s", CRMAPI, "new_main_contracts(" + contractGuid + ")");
        JSONObject retMainJson = new JSONObject();
        //更新合同的json格式
        retMainJson.put("new_group_json", contractEntity.getGroupJson());
        retMainJson.put("new_offer_json", contractEntity.getOfferJson());
        try {
            String retMain = httpAPIServiceForCrm.doUpdateCrm(reqUrlMain, retMainJson.toJSONString());
            return "临时处理-更新合同成功:" + retMain;
        } catch (Exception e) {
            log.info("临时处理-更新合同主表异常========>", contractEntity.getSequenceNo());
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public String pushContractReplaceToCrm(String id) {
        BpmContractReplaceV3Entity entity = bpmContractReplaceRepository.getBpmContractReplaceObject(id);
        //bpm 需要导入的对象转换 输出需要处理的数据
        Map<String, Object> retItems = convertBpmEntityReplaceToCrm(entity);
        List<CrmContractItem> insertItems = (List) retItems.get("insertItems");
        //存放需要删除的对象List
        List<CrmContractItem> deleteItems = (List) retItems.get("deleteItems");
        log.info("处理合同产品替换展示需要替换及需要停用的数据====>>{}", JSONObject.toJSONString(retItems));
        //开始执行处理
        String crmContractId = entity.getNew_contract_id();
        //获取id合同下所有明细
        String reqUrl = String.format("%s%s", CRMAPI, "new_sub_contracts?$expand=new_contract($select=new_name,new_contract_name,new_cdefine12),new_kehu($select=name,new_erp_num),new_product($select=new_name,new_code)&$filter=_new_contract_value eq '" + crmContractId + "'");
        reqUrl = DingUtil.urlEcode(reqUrl);
        String ret = null;
        try {
            ret = httpAPIServiceForCrm.doGetCrm(reqUrl);
        } catch (Exception e) {
            log.info("替换-->获取合同明细异常===>>>{}", entity.getSequenceNo());
            e.printStackTrace();
        }
        JSONObject retJson = JSONObject.parseObject(ret);
        JSONArray retValue = retJson.getJSONArray("value");
        if (retValue.isEmpty()) {
            log.info("原合同为空 不可替换");
            return null;
        }
        //获取并处理停用记录
        List<String> stopSubContract = new ArrayList<>();
        for (Object retValueObj : retValue) {
            JSONObject _retValueObj = (JSONObject) retValueObj;
            String _productName = _retValueObj.getString("new_cinvname");
            String _productCode = _retValueObj.getString("new_cinvcode");
            String _groupId = _retValueObj.getString("new_group_id");
            double _offerPrice = object2Double(_retValueObj.getDouble("new_itaxprice"));
            //内部deleteItems循环
            for (CrmContractItem crmContractItem : deleteItems) {
                if (crmContractItem.getNew_cinvname().equals(_productName) && crmContractItem.getNew_cinvcode().equals(_productCode) && crmContractItem.getNew_group_id().equals(_groupId) && crmContractItem.getNew_itaxprice() == _offerPrice) {
                    //条件比对都 符合停用条件
                    String _sub_contract_id = _retValueObj.getString("new_sub_contractid");
                    stopSubContract.add(_sub_contract_id);
                    break;
                }
            }

        }
        //处理停用记录
        //创建停用Json对象
        JSONObject reqStopJson = new JSONObject();
        reqStopJson.put("statecode", 1);
        for (String s : stopSubContract) {
            String stopSubUrl = String.format("%s%s", CRMAPI, "new_sub_contracts(" + s + ")");
            try {
                httpAPIServiceForCrm.doUpdateCrm(stopSubUrl, reqStopJson.toJSONString());
                log.info("替换-->停用合同明细reqStopJson===>>>{}", s);
            } catch (Exception e) {
                log.info("替换-->停用合同明细异常===>>>{}", entity.getSequenceNo());
                e.printStackTrace();
            }
            log.info("替换--停用合同明细执行完成");
        }

        //执行替换的新纪录到合同中
        //执行推送
        String reqInsertUrl = String.format("%s%s", CRMAPI, "new_sub_contracts");
        for (CrmContractItem item : insertItems) {
            //需要转化下对象
            JSONObject reqJson = JSONObject.parseObject(JSONObject.toJSONString(item));
            reqJson.remove("new_kehuodatabind");
            //新增对象
            reqJson.put("new_contract@odata.bind", "/new_contracts(" + crmContractId + ")");
            reqJson.put("new_kehu@odata.bind", "/accounts(" + entity.getCrmCustomerId() + ")");
            //请求
            try {
                httpAPIServiceForCrm.doPostCrm(reqInsertUrl, reqJson.toJSONString());
                log.info("替换-->新增合同明细reqJson===>>>{}", reqJson.toJSONString());
            } catch (Exception e) {
                log.info("替换-->新增合同明细异常===>>>{}", entity.getSequenceNo());
                e.printStackTrace();
            }
        }

        //更新主表信息
        //处理groupJson内容
        JSONArray newGroupJson = (JSONArray) retItems.get("newGroupJson");
        JSONArray newOfferJson = (JSONArray) retItems.get("newOfferJson");
        String reqUrlMain = String.format("%s%s", CRMAPI, "new_main_contracts(" + crmContractId + ")");
        JSONObject retMainJson = new JSONObject();
        retMainJson.put("new_total", object2Double(entity.getNewContractOffer()));
        //更新合同的json格式
        retMainJson.put("new_group_json", newGroupJson.toJSONString());
        retMainJson.put("new_offer_json", newOfferJson.toJSONString());
        try {
            httpAPIServiceForCrm.doUpdateCrm(reqUrlMain, retMainJson.toJSONString());
            log.info("更新合同主表retMainJson========>{}", retMainJson.toJSONString());
            return "更新合同主表关键字段成功:" + entity.getSequenceNo();
        } catch (Exception e) {
            log.info("更新合同主表异常========>{}", entity.getSequenceNo());
            e.printStackTrace();
            return null;
        }

    }

    @Override
    public String pushContractAppendToCrm(String id) {
        BpmContractAppendV3Entity entity = bpmContractAppendRepository.getBpmContractAppendObject(id);
        //bpm 需要导入的对象转换
        List<CrmContractItem> retItems = convertBpmEntityAppendToCrm(entity);
        log.info("需要新增的明细====>>{}", JSONObject.toJSONString(retItems));
        //执行推送
        //使用私有方法改进追加及增加数量
        try {
            hasItemUpdate(retItems, entity);
            return null;
        } catch (Exception e) {
            log.info("追加或调整增加数量时,出现异常");
            return null;
        }

        //更新主表信息
//        String reqUrlMain = String.format("%s%s", CRMAPI, "new_main_contracts(" + entity.getNew_contract_id() + ")");
//        JSONObject retMainJson = new JSONObject();
//        retMainJson.put("new_total", object2Double(entity.getNewContractOffer()));
//        //更新合同的json格式
//        retMainJson.put("new_group_json", entity.getGroupJson());
//        retMainJson.put("new_offer_json", entity.getOfferJson());
//
//        try {
//            String retMain = httpAPIServiceForCrm.doUpdateCrm(reqUrlMain, retMainJson.toJSONString());
//            return "更新合同成功:" + entity.getSequenceNo();
//        } catch (Exception e) {
//            log.info("更新合同主表异常========>{}", entity.getSequenceNo());
//            e.printStackTrace();
//            return null;
//        }
    }

    /**
     * appendContract的扩展功能,比对原合同中已经存在的合同条目,更新数量 做调整
     */
    private void hasItemUpdate(List<CrmContractItem> items, BpmContractAppendV3Entity entity) throws Exception {
        //当前合同明细
        String contractId = entity.getNew_contract_id();
        //获取合同明细
        String url = String.format("%s%s", CRMAPI, "new_sub_contracts?$expand=new_contract($select=new_name,new_contract_name,new_cdefine12),new_kehu($select=name,new_erp_num),new_product($select=new_name,new_code)&$filter=_new_contract_value eq '" + contractId + "' and statecode eq 0");
        url = DingUtil.urlEcode(url);
        //请求crm合同信息
        String ret = httpAPIServiceForCrm.doGetCrm(url);
        JSONObject retJson = JSONObject.parseObject(ret);
        JSONArray retArray = retJson.getJSONArray("value");
        if (!retArray.isEmpty()) {
            for (CrmContractItem item : items) {
                int flag = 0;//0=编码在原合同中找不到的 1=编码和单价相等(进行数量叠加) 2=不处理
                String itemCinvcode = item.getNew_cinvcode();
                double itemItaxprice = object2Double(item.getNew_itaxprice());
                String itemId = "";
                double iquanity = 0.00;
                double itaxprice = 0.00;
                String cinvcode = "";
                for (Object obj : retArray) {
                    JSONObject jsonObject = (JSONObject) obj;
                    itemId = jsonObject.getString("new_sub_contractid");
                    iquanity = object2Double(jsonObject.getDouble("new_iquantity"));
                    itaxprice = object2Double(jsonObject.getDouble("new_itaxprice"));
                    cinvcode = jsonObject.getString("new_cinvcode");
                    if (itemCinvcode.equals(cinvcode) && itemItaxprice == itaxprice) {
                        flag = 1;
                        break;
                    }
                    if (itemCinvcode.equals(cinvcode)) {
                        flag = 2;
                        break;
                    }
                }

                if (flag == 1) {
                    //产品一致,价格一致 触发修改逻辑
                    double newIquanity = iquanity + item.getNew_iquantity();
                    double newInatsum = newIquanity * item.getNew_itaxprice();

                    String urlTmp = String.format("%s%s", CRMAPI, "new_sub_contracts(" + itemId + ")");
                    JSONObject tmpJson = new JSONObject();
                    tmpJson.put("new_iquantity", newIquanity);
                    tmpJson.put("new_inatsum", newInatsum);
                    log.info("触发跟新动作===>" + tmpJson.toJSONString() + "||url==>>" + urlTmp);

                    String retTmp = httpAPIServiceForCrm.doUpdateCrm(urlTmp, JSONObject.toJSONString(tmpJson));
                    log.info("追加--修改合同明细动作===>>>{}", retTmp);
                } else if (flag == 0) {
                    //任意不一致,触发插入逻辑
                    String reqUrl = String.format("%s%s", CRMAPI, "new_sub_contracts");
                    JSONObject reqJson = JSONObject.parseObject(JSONObject.toJSONString(item));
                    reqJson.remove("new_kehuodatabind");
                    //新增对象
                    reqJson.put("new_contract@odata.bind", "/new_contracts(" + entity.getNew_contract_id() + ")");
                    reqJson.put("new_kehu@odata.bind", "/accounts(" + entity.getCrmCustomerId() + ")");
                    log.info("触发插入动作===>" + reqJson.toJSONString() + " url====>"+reqUrl);
                    //请求
                    try {
                        String retTmp = httpAPIServiceForCrm.doPostCrm(reqUrl, reqJson.toJSONString());
                        log.info("追加--插入合同明细动作===>>>{}", retTmp);
                    } catch (Exception e) {
                        log.info("追加合同明细异常===>>>{}", entity.getSequenceNo());
                        e.printStackTrace();
                    }
                }

            }
        }
    }

    /**
     * 用于 合同替换的 对象装换 输出需要添加的合同明细及需要停用的合同明细
     * 1.List<CrmContractItem> 2.JSONArray
     */
    private Map<String, Object> convertBpmEntityReplaceToCrm(BpmContractReplaceV3Entity entity) {
        //获取新报价合计
        double new_total = object2Double(entity.getNewContractOffer());
        String groupJson = entity.getGroupJson();
        String offerJson = entity.getOfferJson();
        //存放需要插入的对象List
        List<CrmContractItem> insertItems = new ArrayList<>();
        //存放需要删除的对象List
        List<CrmContractItem> deleteItems = new ArrayList<>();
        //处理groupJson
        if (StringUtils.isNotBlank(groupJson)) {
            //转为jsonarray对象
            JSONArray groupJsonArray = JSONArray.parseArray(groupJson);
            for (int i = 0; i < groupJsonArray.size(); i++) {
                JSONObject groupJsonObject = groupJsonArray.getJSONObject(i);
                JSONArray groupChildrenArray = groupJsonObject.getJSONArray("_X_ROW_CHILD");
                //当前套的报价合计
                double offerPrice = object2Double(groupJsonObject.getDouble("offerPrice"));
                //主产品编码
                String mainKeyProductCode = "";
                for (int j = 0; j < groupChildrenArray.size(); j++) {
                    JSONObject _groupChildrenArrayObj = groupChildrenArray.getJSONObject(j);
                    //获取删除标识
                    String _deleteFlag = _groupChildrenArrayObj.getString("deleteFlag");
                    //获取替换标识
                    String _gourpFlag = _groupChildrenArrayObj.getString("gourpFlag");
                    if (StringUtils.isNotBlank(_deleteFlag) && _deleteFlag.equals("1")) {
                        //需要删除的对象记录
                        String productCode = _groupChildrenArrayObj.getString("productCode");
                        mainKeyProductCode = _groupChildrenArrayObj.getString("mainKeyProductCode");
                        CrmContractItem item = new CrmContractItem();
                        //子项产品名称
                        item.setNew_cinvname(_groupChildrenArrayObj.getString("productName"));
                        //子项产品编码
                        item.setNew_cinvcode(_groupChildrenArrayObj.getString("productCode"));
                        //groupid
                        item.setNew_group_id(_groupChildrenArrayObj.getString("groupId"));
                        //含税单价
                        if (StringUtils.isNotBlank(mainKeyProductCode) && mainKeyProductCode.equals(productCode)) {
                            item.setNew_itaxprice(offerPrice);
                        } else {
                            item.setNew_itaxprice(object2Double(_groupChildrenArrayObj.getDouble("offerPrice")));
                        }
                        //新版合同标识
                        deleteItems.add(item);
                    }
                    if (StringUtils.isNotBlank(_gourpFlag) && _gourpFlag.equals("替换")) {
                        //需要替换的对象记录
                        CrmContractItem item = new CrmContractItem();
                        String productCode = _groupChildrenArrayObj.getString("productCode");
                        mainKeyProductCode = _groupChildrenArrayObj.getString("mainKeyProductCode");
                        //合同子项明细name
                        String _name = "ContractReplace-group-" + i + "-" + j;
                        item.setNew_name(_name);
                        //子项产品名称
                        item.setNew_cinvname(_groupChildrenArrayObj.getString("productName"));
                        //子项产品编码
                        item.setNew_cinvcode(productCode);
                        //子项产品数量
                        item.setNew_iquantity(object2Double(_groupChildrenArrayObj.getDouble("quantity")));
                        //子项产单位
                        item.setNew_cunitname(_groupChildrenArrayObj.getString("unit"));
                        //子项税率
                        item.setNew_itaxrate(productCodeToTax(productCode));
                        //含税单价
                        if (StringUtils.isNotBlank(mainKeyProductCode) && mainKeyProductCode.equals(productCode)) {
                            item.setNew_itaxprice(offerPrice);
                        } else {
                            item.setNew_itaxprice(object2Double(_groupChildrenArrayObj.getDouble("offerPrice")));
                        }
                        //明细小计金额 = 原币金额\本币金额
                        double _isum = item.getNew_iquantity() * item.getNew_itaxprice();
                        item.setNew_isum(_isum);
                        //明细本币金额
                        item.setNew_inatsum(_isum);
                        //合同子项开始时间
                        item.setNew_dstart(StrUtil.convertGMTDateTime(entity.getNew_dstart()));
                        //合同子项结束时间
                        item.setNew_dend(StrUtil.convertGMTDateTime(entity.getNew_dend()));
                        //质保到期日期 默认不写
                        item.setNew_dzbdate(null);
                        //子项备注
                        item.setNew_cmemos("流程追加:" + entity.getSequenceNo() + "||" + _groupChildrenArrayObj.getString("memo"));
                        //子项交货日期
                        item.setNew_dcheckdate(null);
                        //子项客户guid
                        item.setNew_kehuodatabind(String.format("/accounts(%s)", entity.getNew_kehu()));
                        //v3版本新增字段
                        //groupid
                        item.setNew_group_id(_groupChildrenArrayObj.getString("groupId"));
                        //groupname
                        item.setNew_group_name(_groupChildrenArrayObj.getString("groupName"));
                        //main_key
                        item.setNew_main_key_product_code(_groupChildrenArrayObj.getString("mainKeyProductCode"));
                        //parent_id
                        item.setNew_parent_group_id(_groupChildrenArrayObj.getString("parentGroupId"));
                        //propor
                        item.setNew_propor(object2Double(_groupChildrenArrayObj.getDouble("proportion")));
                        //新版合同标识
                        item.setNew_system_version("3");
                        insertItems.add(item);
                    }
                }
            }
        }

        //处理offerJson
        if (StringUtils.isNotBlank(offerJson)) {
            JSONArray offerArrayJson = JSONArray.parseArray(offerJson);
            for (int i = 0; i < offerArrayJson.size(); i++) {
                JSONObject _offerArrayObj = offerArrayJson.getJSONObject(i);
                //获取删除标识
                String _deleteFlag = _offerArrayObj.getString("deleteFlag");
                //获取替换标识
                String _gourpFlag = _offerArrayObj.getString("gourpFlag");
                if (StringUtils.isNotBlank(_deleteFlag) && _deleteFlag.equals("1")) {
                    //需要删除的对象记录
                    CrmContractItem item = new CrmContractItem();
                    //子项产品名称
                    item.setNew_cinvname(_offerArrayObj.getString("productName"));
                    //子项产品编码
                    item.setNew_cinvcode(_offerArrayObj.getString("productCode"));
                    //groupid
                    item.setNew_group_id(_offerArrayObj.getString("groupId"));
                    //新版合同标识
                    deleteItems.add(item);
                }
                if (StringUtils.isNotBlank(_gourpFlag) && _gourpFlag.equals("替换")) {
                    //需要替换的对象记录
                    CrmContractItem item = new CrmContractItem();
                    String productCode = _offerArrayObj.getString("productCode");
                    //合同子项明细name
                    String _name = "ContractReplace-group-" + i;
                    item.setNew_name(_name);
                    //子项产品名称
                    item.setNew_cinvname(_offerArrayObj.getString("productName"));
                    //子项产品编码
                    item.setNew_cinvcode(productCode);
                    //子项产品数量
                    item.setNew_iquantity(object2Double(_offerArrayObj.getDouble("quantity")));
                    //子项产单位
                    item.setNew_cunitname(_offerArrayObj.getString("unit"));
                    //子项税率
                    item.setNew_itaxrate(productCodeToTax(productCode));
                    //含税单价
                    item.setNew_itaxprice(object2Double(_offerArrayObj.getDouble("offerPrice")));
                    //明细小计金额 = 原币金额\本币金额
                    double _isum = item.getNew_iquantity() * item.getNew_itaxprice();
                    item.setNew_isum(_isum);
                    //明细本币金额
                    item.setNew_inatsum(_isum);
                    //合同子项开始时间
                    item.setNew_dstart(StrUtil.convertGMTDateTime(entity.getNew_dstart()));
                    //合同子项结束时间
                    item.setNew_dend(StrUtil.convertGMTDateTime(entity.getNew_dend()));
                    //质保到期日期 默认不写
                    item.setNew_dzbdate(null);
                    //子项备注
                    item.setNew_cmemos("流程追加:" + entity.getSequenceNo() + "||" + _offerArrayObj.getString("memo"));
                    //子项交货日期
                    item.setNew_dcheckdate(null);
                    //子项客户guid
                    item.setNew_kehuodatabind(String.format("/accounts(%s)", entity.getNew_kehu()));
                    //v3版本新增字段
                    //groupid
                    item.setNew_group_id(null);
                    //groupname
                    item.setNew_group_name(null);
                    //main_key
                    item.setNew_main_key_product_code(null);
                    //parent_id
                    item.setNew_parent_group_id(null);
                    //propor
                    item.setNew_propor(1.00);
                    //新版合同标识
                    item.setNew_system_version("3");
                    insertItems.add(item);
                }
            }
        }

        //groupJson 和 offerJson 整理完毕 返回
        Map<String, Object> ret = new HashMap<>();
        ret.put("insertItems", insertItems);
        ret.put("deleteItems", deleteItems);

        //循环处理groupJson和offerJson记录
        JSONArray newGroupJsonArray = new JSONArray();
        if (StringUtils.isNotBlank(groupJson)) {
            newGroupJsonArray = JSONArray.parseArray(groupJson);
            for (Object object : newGroupJsonArray) {
                JSONObject _jsonObject = (JSONObject) object;
                JSONArray _groupJsonArray = _jsonObject.getJSONArray("_X_ROW_CHILD");
                List<JSONObject> toRemoves = new ArrayList<>();
                for (Object object1 : _groupJsonArray) {
                    JSONObject __jsonObject = (JSONObject) object1;
                    if (__jsonObject.containsKey("deleteFlag") && "1".equals(String.valueOf(__jsonObject.get("deleteFlag")))) {
                        //符合条件 删除这个对象
                        toRemoves.add(__jsonObject);
                    }
                }
                _groupJsonArray.removeAll(toRemoves);
            }
        }

        JSONArray newOfferJsonArray = new JSONArray();
        if (StringUtils.isNotBlank(offerJson)) {
            newOfferJsonArray = JSONArray.parseArray(offerJson);
            List<JSONObject> toRemoves = new ArrayList<>();

            for (Object object : newOfferJsonArray) {
                JSONObject _jsonObject = (JSONObject) object;
                if (_jsonObject.containsKey("deleteFlag") && _jsonObject.getString("deleteFlag").equals("1")) {
                    toRemoves.add(_jsonObject);
                }
            }
            newOfferJsonArray.removeAll(toRemoves);
        }

        //放入map中返回
        ret.put("newGroupJson", newGroupJsonArray);
        ret.put("newOfferJson", newOfferJsonArray);

        return ret;
    }


    /**
     * 用于 合同追加的 对象转换 输出 需要添加的合同明细
     * 增加 临时处理逻辑 前段quantity字段可能为0,就需要直接进行计算得出
     *
     * @param entity
     */
    private List<CrmContractItem> convertBpmEntityAppendToCrm(BpmContractAppendV3Entity entity) {
        //主表基本不用动
        double new_total = object2Double(entity.getNewContractOffer());
        String groupJson = entity.getGroupJson();
        String offerJson = entity.getOfferJson();
        //明细表追加
        List<CrmContractItem> items = new ArrayList<>();
        //处理groupJson转换
        if (StringUtils.isNotBlank(groupJson)) {
            JSONArray groupJsonArray = JSONArray.parseArray(groupJson);
            for (int i = 0; i < groupJsonArray.size(); i++) {
                JSONObject groupJsonObject = groupJsonArray.getJSONObject(i);
                JSONArray groupChildrenArray = groupJsonObject.getJSONArray("_X_ROW_CHILD");
                //定义组套的报价
                double offerPrice = object2Double(groupJsonObject.getDouble("offerPrice"));
                //定义 组套的数量
                double mainQuantity = object2Double(groupJsonObject.getDouble("quantity"));
                //定义主产品编码
                String mainKeyProductCode = "";
                //开始循环转换
                if(Objects.isNull(groupChildrenArray)){
                    continue;
                }
                for (int j = 0; j < groupChildrenArray.size(); j++) {
                    JSONObject _groupChildObject = groupChildrenArray.getJSONObject(j);
                    String _isContract = StringUtils.isBlank(_groupChildObject.getString("isContract")) ? "" : _groupChildObject.getString("isContract");
                    if (StringUtils.isBlank(_isContract) || !_isContract.equals("1")) {
                        //需要追加到已有合同的对象
                        CrmContractItem item = new CrmContractItem();
                        String productCode = _groupChildObject.getString("productCode");
                        mainKeyProductCode = _groupChildObject.getString("mainKeyProductCode");
                        double productOfferPrice=object2Double(_groupChildObject.getDouble("offerPrice"));
                        //合同子项明细name
                        String _name = "ContractAppend-group-" + i + "-" + j;
                        item.setNew_name(_name);
                        //子项产品名称
                        item.setNew_cinvname(_groupChildObject.getString("productName"));
                        //子项产品编码
                        item.setNew_cinvcode(productCode);
                        //子项产品数量
                        double _quantity=object2Double(_groupChildObject.getDouble("quantity"));
                        if(_quantity==0){
                            _quantity=object2Double(_groupChildObject.getDouble("proportion"))*mainQuantity;
                            item.setNew_iquantity(_quantity);
                        }else{
                            item.setNew_iquantity(object2Double(_groupChildObject.getDouble("quantity")));
                        }

                        //子项产单位
                        item.setNew_cunitname(_groupChildObject.getString("unit"));
                        //子项税率
                        item.setNew_itaxrate(productCodeToTax(productCode));
                        //含税单价
                        if (StringUtils.isNotBlank(mainKeyProductCode) && mainKeyProductCode.equals(productCode)) {
                            //内部嵌套 二次判定 是否可以写套装的价格
                            if(productOfferPrice==0){
                                item.setNew_itaxprice(offerPrice);
                            }else{
                                item.setNew_itaxprice(object2Double(_groupChildObject.getDouble("offerPrice")));
                            }
                        } else {
                            item.setNew_itaxprice(object2Double(_groupChildObject.getDouble("offerPrice")));
                        }
                        //明细小计金额 = 原币金额\本币金额
                        double _isum = item.getNew_iquantity() * item.getNew_itaxprice();
                        item.setNew_isum(_isum);
                        //明细本币金额
                        item.setNew_inatsum(_isum);
                        //合同子项开始时间
                        item.setNew_dstart(StrUtil.convertGMTDateTime(entity.getNew_dstart()));
                        //合同子项结束时间
                        item.setNew_dend(StrUtil.convertGMTDateTime(entity.getNew_dend()));
                        //质保到期日期 默认不写
                        item.setNew_dzbdate(null);
                        //子项备注
                        item.setNew_cmemos("流程追加:" + entity.getSequenceNo() + "||" + _groupChildObject.getString("memo"));
                        //子项交货日期
                        item.setNew_dcheckdate(null);
                        //子项客户guid
                        item.setNew_kehuodatabind(String.format("/accounts(%s)", entity.getNew_kehu()));
                        //v3版本新增字段
                        //groupid
                        item.setNew_group_id(_groupChildObject.getString("groupId"));
                        //groupname
                        item.setNew_group_name(_groupChildObject.getString("groupName"));
                        //main_key
                        item.setNew_main_key_product_code(_groupChildObject.getString("mainKeyProductCode"));
                        //parent_id
                        item.setNew_parent_group_id(_groupChildObject.getString("parentGroupId"));
                        //propor
                        item.setNew_propor(object2Double(_groupChildObject.getDouble("proportion")));
                        //新版合同标识
                        item.setNew_system_version("3");
                        items.add(item);
                    }
                }
            }
        }

        //处理offerJson转换
        if (StringUtils.isNotBlank(offerJson)) {
            JSONArray offerArrayJson = JSONArray.parseArray(offerJson);
            for (int i = 0; i < offerArrayJson.size(); i++) {
                JSONObject offerJsonObject = offerArrayJson.getJSONObject(i);
                String _isContract = StringUtils.isBlank(offerJsonObject.getString("isContract")) ? "" : offerJsonObject.getString("isContract");
                if (StringUtils.isBlank(_isContract) || !_isContract.equals("1")) {
                    //新追加的产品
                    CrmContractItem item = new CrmContractItem();
                    String productCode = offerJsonObject.getString("productCode");
                    //合同子项明细name
                    String _name = "ContractAppend-offer-" + i;
                    item.setNew_name(_name);
                    //子项产品名称
                    item.setNew_cinvcode(offerJsonObject.getString("productName"));
                    //子项产品编码
                    item.setNew_cinvcode(productCode);
                    //子项产品数量
                    item.setNew_iquantity(object2Double(offerJsonObject.getDouble("quantity")));
                    //子项产单位
                    item.setNew_cunitname(offerJsonObject.getString("unit"));
                    //子项税率
                    item.setNew_itaxrate(productCodeToTax(productCode));
                    //含税单价
                    item.setNew_itaxprice(object2Double(offerJsonObject.getDouble("offerPrice")));
                    //明细小计金额 = 原币金额\本币金额
                    double _isum = item.getNew_iquantity() * item.getNew_itaxprice();
                    item.setNew_isum(_isum);
                    //明细本币金额
                    item.setNew_inatsum(_isum);
                    //合同子项开始时间
                    item.setNew_dstart(StrUtil.convertGMTDateTime(entity.getNew_dstart()));
                    //合同子项结束时间
                    item.setNew_dend(StrUtil.convertGMTDateTime(entity.getNew_dend()));
                    //质保到期日期 默认不写
                    item.setNew_dzbdate(null);
                    //子项备注
                    item.setNew_cmemos("流程追加:" + entity.getSequenceNo() + "||" + offerJsonObject.getString("memo"));
                    //子项交货日期
                    item.setNew_dcheckdate(null);
                    //子项客户guid
                    item.setNew_kehuodatabind(String.format("/accounts(%s)", entity.getNew_kehu()));
                    //v3版本新增字段
                    //groupid
                    item.setNew_group_id(null);
                    //groupname
                    item.setNew_group_name(null);
                    //main_key
                    item.setNew_main_key_product_code(null);
                    //parent_id
                    item.setNew_parent_group_id(null);
                    //propor 单一产品 给配比默认为1
                    item.setNew_propor(1.00);
                    //新版合同标识
                    item.setNew_system_version("3");
                    items.add(item);
                }

            }
        }
        return items;
    }

    @Override
    public String pushContractToCrm(String id) {
        //1.通过id,从bpm数据库中获取合同记录
        BpmContractV3Entity contractEntity = bpmContractRepository.getBpmContract(id);
        //如果对象有推送标识,且有存在CRMBPM推送
        if (contractEntity.getSystemDishOut().contains("CRMBPM")) {
            //bpm对象转换
            CrmContract reqCrmContract = convertBpmEntityToCrm(contractEntity);
            //执行推送
            String reqUrl = String.format("%s%s", CRMAPI, "new_main_contracts");
            try {
                log.info("请求合同报文展示====>>>{}", objectMapper.writeValueAsString(reqCrmContract));
                log.info("===>>>请求推送合同的url展示===>{}", reqUrl);
                String ret = httpAPIServiceForCrm.doPostCrm(reqUrl, objectMapper.writeValueAsString(reqCrmContract));
                //获取创建合同的guid
                Map<String, Object> retMap = objectMapper.readValue(ret, Map.class);
                String retStr = retMap.get("new_main_contractid").toString();
                return retStr;
            } catch (Exception e) {
                log.info("推送创建crm合同出现异常");
                e.printStackTrace();
                return null;
            }
        } else {
            return "手动处理";
        }
    }

    /**
     * 用于转换
     *
     * @param contractEntity
     */
    private CrmContract convertBpmEntityToCrm(BpmContractV3Entity contractEntity) {
        //配置crm合同主表
        CrmContract crmContract = new CrmContract();
        //合同开始时间
        crmContract.setNew_dstartdate(StrUtil.convertGMTDateTime(contractEntity.getStartDate()));
        //合同结束时间
        crmContract.setNew_denddate(StrUtil.convertGMTDateTime(contractEntity.getEndDate()));
        //合同签订日期
        crmContract.setNew_dsigndate(StrUtil.convertGMTDateTime(contractEntity.getDsignDate()));
        //质保金额度
        crmContract.setNew_dblmassassure(0.00);
        //合同描述-合同说明
        crmContract.setNew_desc(contractEntity.getContract_note());
        //合同编码-BPM合同流程编码
        crmContract.setNew_name(contractEntity.getSequenceNo());
        //合同名称--合同标题
        crmContract.setNew_contract_name(contractEntity.getContractTitle());
        //用章单位
        crmContract.setNew_cunit(contractEntity.getSkipCompany());
        //部门--BPM部门
        String _deptName = bpmContractRepository.getBpmDeptName(contractEntity.getCreatedDeptId());
        //汇率 默认值 1
        crmContract.setNew_cdepname("1");
        //币种 默认值 人民币
        crmContract.setNew_exchname("人民币");
        //客户名称
        crmContract.setNew_ccusname(contractEntity.getAccount_name());
        //业务员
        String _userName = bpmContractRepository.getBpmUserName(contractEntity.getCreater());
        crmContract.setNew_cpersonname(_userName);
        //保修期 默认空
        crmContract.setNew_repair("");
        //制单人 默认值
        crmContract.setNew_cmaker("BpmPush");
        //生效人
        crmContract.setNew_csign("刘昕");
        //合同类型--合同管理分类(内部合同-正式合同)
        crmContract.setNew_cdefine12(contractEntity.getSaleman_contract_type());
        //收款方式
        crmContract.setNew_chdefine2(contractEntity.getReceipt_note());
        //存放位置
        crmContract.setNew_cdefine13(contractEntity.getSiteNum());
        //是否有中标通知书
        crmContract.setNew_chdefine1(contractEntity.getBidLetter());
        //最终客户
        crmContract.setNew_cendcustomer(contractEntity.getZuizongname());
        //客户对应Crm Guid
        crmContract.setNew_new_crmcustomeridodatabind(String.format("/accounts(%s)", contractEntity.getAccount_id()));
        //发货公司对应guid
        crmContract.setNew_company(companyNameToGuid(contractEntity.getSkipCompany()));
        //账套号 配置默认值 111
        crmContract.setNew_ccid("111");
        //合同总金额  报价合计
        crmContract.setNew_total(object2Double(contractEntity.getOfferSum()));
        //营销合同分类
        crmContract.setNew_sale_contract_type(contractEntity.getSale_contract_type());
        //合同合规分类
        crmContract.setNew_sale_compliance_type(contractEntity.getSale_compliance_type());
        //合同合规状态 - 合规状态
        crmContract.setNew_compliance_state(contractEntity.getCompliance_state());
        //合同状态 -合同状态
        crmContract.setNew_contractstate(contractEntity.getContractState());
        //合同版本 V3版本合同给默认值
        crmContract.setNew_system_version("3");
        //合同offerJson
        crmContract.setNew_offer_json(contractEntity.getOfferJson());
        //合同groupJson
        crmContract.setNew_group_json(contractEntity.getGroupJson());

        //转换合同明细+ 配置crm合同子项
        List<CrmContractItem> items = handlerContractItem(contractEntity);
        crmContract.setContractItems(items);
        return crmContract;
    }

    /**
     * 合同明细行的转换处理
     *
     * @param entity
     * @return
     */
    private List<CrmContractItem> handlerContractItem(BpmContractV3Entity entity) {
        String groupJson = entity.getGroupJson();
        String offerJson = entity.getOfferJson();
        List<CrmContractItem> items = new ArrayList<>();
        //处理groupJson转换
        if (StringUtils.isNotBlank(groupJson)) {
            JSONArray groupJsonArray = JSONArray.parseArray(groupJson);
            for (int i = 0; i < groupJsonArray.size(); i++) {
                JSONObject groupJsonObject = groupJsonArray.getJSONObject(i);
                JSONArray groupChildrenArray = groupJsonObject.getJSONArray("_X_ROW_CHILD");
                //关键点定义-获取当前项目套的报价 如果为0,代表需要进行分享报价;如果大于0,代表项目报价放入主试剂中
                double offerPrice = object2Double(groupJsonObject.getDouble("offerPrice"));
                //定义主产品编码
                String mainKeyProductCode = "";
                //开始循环转换
                for (int j = 0; j < groupChildrenArray.size(); j++) {
                    //项目(标准套)实际明细行
                    JSONObject _groupChildObject = groupChildrenArray.getJSONObject(j);
                    CrmContractItem item = new CrmContractItem();
                    String productCode = _groupChildObject.getString("productCode");
                    mainKeyProductCode = _groupChildObject.getString("mainKeyProductCode");
                    //合同子项明细name
                    String _name = entity.getSequenceNo() + "-group-" + i + "-" + j;
                    item.setNew_name(_name);
                    //子项产品名称
                    item.setNew_cinvname(_groupChildObject.getString("productName"));
                    //子项产品编码
                    item.setNew_cinvcode(productCode);
                    //子项产品数量
                    item.setNew_iquantity(object2Double(_groupChildObject.getDouble("quantity")));
                    //子项产单位
                    item.setNew_cunitname(_groupChildObject.getString("unit"));
                    //子项税率
                    item.setNew_itaxrate(productCodeToTax(productCode));
                    //含税单价 增加 如果项目套为0,代表合同需要分项录入;如果项目套不为0,代表合同需要把项目套单价录入到主试剂上;如果整个都是免费赠送,不影像逻辑
                    if (StringUtils.isNotBlank(mainKeyProductCode) && mainKeyProductCode.equals(productCode) && offerPrice != 0.00) {
                        item.setNew_itaxprice(offerPrice);
                    } else {
                        item.setNew_itaxprice(object2Double(_groupChildObject.getDouble("offerPrice")));
                    }
                    //明细小计金额 = 原币金额\本币金额
                    double _isum = item.getNew_iquantity() * item.getNew_itaxprice();
                    item.setNew_isum(_isum);
                    //明细本币金额
                    item.setNew_inatsum(_isum);
                    //合同子项开始时间
                    item.setNew_dstart(StrUtil.convertGMTDateTime(entity.getStartDate()));
                    //合同子项结束时间
                    item.setNew_dend(StrUtil.convertGMTDateTime(entity.getEndDate()));
                    //质保到期日期 默认不写
                    item.setNew_dzbdate(null);
                    //子项备注
                    item.setNew_cmemos(_groupChildObject.getString("memo"));
                    //子项交货日期
                    item.setNew_dcheckdate(null);
                    //子项客户guid
                    item.setNew_kehuodatabind(String.format("/accounts(%s)", entity.getAccount_id()));
                    //v3版本新增字段
                    //groupid
                    item.setNew_group_id(_groupChildObject.getString("groupId"));
                    //groupname
                    item.setNew_group_name(_groupChildObject.getString("groupName"));
                    //main_key
                    item.setNew_main_key_product_code(_groupChildObject.getString("mainKeyProductCode"));
                    //parent_id
                    item.setNew_parent_group_id(_groupChildObject.getString("parentGroupId"));
                    //propor
                    item.setNew_propor(object2Double(_groupChildObject.getDouble("proportion")));
                    //新版合同标识
                    item.setNew_system_version("3");
                    items.add(item);
                }
            }
        }

        //处理offerJson转换
        if (StringUtils.isNotBlank(offerJson)) {
            JSONArray offerArrayJson = JSONArray.parseArray(offerJson);
            for (int i = 0; i < offerArrayJson.size(); i++) {
                JSONObject offerJsonObject = offerArrayJson.getJSONObject(i);
                CrmContractItem item = new CrmContractItem();
                String productCode = offerJsonObject.getString("productCode");
                //合同子项明细name
                String _name = entity.getSequenceNo() + "-offer-" + i;
                item.setNew_name(_name);
                //子项产品名称
                item.setNew_cinvcode(offerJsonObject.getString("productName"));
                //子项产品编码
                item.setNew_cinvcode(productCode);
                //子项产品数量
                item.setNew_iquantity(object2Double(offerJsonObject.getDouble("quantity")));
                //子项产单位
                item.setNew_cunitname(offerJsonObject.getString("unit"));
                //子项税率
                item.setNew_itaxrate(productCodeToTax(productCode));
                //含税单价
                item.setNew_itaxprice(object2Double(offerJsonObject.getDouble("offerPrice")));
                //明细小计金额 = 原币金额\本币金额
                double _isum = item.getNew_iquantity() * item.getNew_itaxprice();
                item.setNew_isum(_isum);
                //明细本币金额
                item.setNew_inatsum(_isum);
                //合同子项开始时间
                item.setNew_dstart(StrUtil.convertGMTDateTime(entity.getStartDate()));
                //合同子项结束时间
                item.setNew_dend(StrUtil.convertGMTDateTime(entity.getEndDate()));
                //质保到期日期 默认不写
                item.setNew_dzbdate(null);
                //子项备注
                item.setNew_cmemos(offerJsonObject.getString("memo"));
                //子项交货日期
                item.setNew_dcheckdate(null);
                //子项客户guid
                item.setNew_kehuodatabind(String.format("/accounts(%s)", entity.getAccount_id()));
                //v3版本新增字段
                //groupid
                item.setNew_group_id(null);
                //groupname
                item.setNew_group_name(null);
                //main_key
                item.setNew_main_key_product_code(null);
                //parent_id
                item.setNew_parent_group_id(null);
                //propor 单一产品 给配比默认为1
                item.setNew_propor(1.00);
                //新版合同标识
                item.setNew_system_version("3");
                items.add(item);

            }
        }
        return items;
    }

    /**
     * 获取公司对应 guid
     *
     * @param name
     * @return
     */
    private String companyNameToGuid(String name) {
        String url = String.format("%s%s", CRMAPI, "new_companies?$filter=new_name eq '" + name + "'");
        try {
            url = StrUtil.urlEcode(url);
            String ret = httpAPIServiceForCrm.doGetCrm(url);
            if (StringUtils.isBlank(ret)) {
                return null;
            } else {
                JSONObject jsonObject = JSONObject.parseObject(ret);
                JSONArray jsonArray = jsonObject.getJSONArray("value");
                JSONObject jsonObject1 = (JSONObject) jsonArray.get(0);
                String res = String.format("/new_companies(%s)", jsonObject1.getString("new_companyid"));
                return res;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 转换税率
     */
    private double productCodeToTax(String code) {
        if (code.contains("FW04")) {
            return 9.00;
        } else if (code.contains("FW")) {
            return 6.00;
        } else {
            return 13.00;
        }
    }
}
